home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1996 #15 / Monster Media Number 15 (Monster Media)(July 1996).ISO / bbs_util / bsrc_260.zip / SRC.ZIP / EMSI.C < prev    next >
C/C++ Source or Header  |  1996-03-23  |  31KB  |  1,272 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                          */
  3. /*                                                                          */
  4. /*      ------------         Bit-Bucket Software, Co.                       */
  5. /*      \ 10001101 /         Writers and Distributors of                    */
  6. /*       \ 011110 /          Freely Available<tm> Software.                 */
  7. /*        \ 1011 /                                                          */
  8. /*         ------                                                           */
  9. /*                                                                          */
  10. /*              (C) Copyright 1987-96, Bit Bucket Software Co.              */
  11. /*                                                                          */
  12. /*              This module was written by Tobias Burchhardt                */
  13. /*                                                                          */
  14. /*                   BinkleyTerm EMSI-Handshake Processor                   */
  15. /*                                                                          */
  16. /*                                                                          */
  17. /*    For complete  details  of the licensing restrictions, please refer    */
  18. /*    to the License  agreement,  which  is published in its entirety in    */
  19. /*    the MAKEFILE and BT.C, and also contained in the file LICENSE.260.    */
  20. /*                                                                          */
  21. /*    USE  OF THIS FILE IS SUBJECT TO THE  RESTRICTIONS CONTAINED IN THE    */
  22. /*    BINKLEYTERM  LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF    */
  23. /*    THIS  AGREEMENT IN ANY OF THE  AFOREMENTIONED FILES,  OR IF YOU DO    */
  24. /*    NOT HAVE THESE FILES,  YOU  SHOULD  IMMEDIATELY CONTACT BIT BUCKET    */
  25. /*    SOFTWARE CO.  AT ONE OF THE  ADDRESSES  LISTED BELOW.  IN NO EVENT    */
  26. /*    SHOULD YOU  PROCEED TO USE THIS FILE  WITHOUT HAVING  ACCEPTED THE    */
  27. /*    TERMS  OF  THE  BINKLEYTERM  LICENSING  AGREEMENT,  OR  SUCH OTHER    */
  28. /*    AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO.      */
  29. /*                                                                          */
  30. /*                                                                          */
  31. /* You can contact Bit Bucket Software Co. at any one of the following      */
  32. /* addresses:                                                               */
  33. /*                                                                          */
  34. /* Bit Bucket Software Co.        FidoNet  1:104/501, 1:343/491             */
  35. /* P.O. Box 460398                AlterNet 7:42/1491                        */
  36. /* Aurora, CO 80046               BBS-Net  86:2030/1                        */
  37. /*                                Internet f491.n343.z1.fidonet.org         */
  38. /*                                                                          */
  39. /* Please feel free to contact us at any time to share your comments about  */
  40. /* our software and/or licensing policies.                                  */
  41. /*                                                                          */
  42. /*--------------------------------------------------------------------------*/
  43.  
  44. /* Include this file before any other includes or defines! */
  45.  
  46. #include "includes.h"
  47.  
  48. static int LOCALFUNC Send_EMSI_Packet (int);
  49. static int LOCALFUNC Recv_EMSI_Packet (int);
  50. static int LOCALFUNC get_emsi (char *);
  51. static char *LOCALFUNC b7strcat (char *, char *);
  52. static int LOCALFUNC recode_from_b7 (char *, int);
  53. static int LOCALFUNC match_aka (ADDRP);
  54. static char *LOCALFUNC get_bracket (char *);
  55. static char *LOCALFUNC cat_bracket (char *, char *);
  56. static int LOCALFUNC get_level (ADDRP addr, ADDRP myaka);
  57. static int LOCALFUNC Encode_EMSI_Header (char *, int);
  58. static int LOCALFUNC Decode_EMSI_Header (char *, int, int);
  59.  
  60. static int highest_level, hl_aka;    /* Used for passwording */
  61.  
  62. /*--------------------------------------------------------------------------*/
  63. /* EMSI SENDER    (used when I am the CALLING system)                       */
  64. /*--------------------------------------------------------------------------*/
  65.  
  66. int 
  67. EMSI_Sender (void)
  68. {
  69.     char *sptr;
  70.  
  71.     highest_level = hl_aka = num_rakas = 0;
  72.     sptr = NULL;
  73.  
  74.     if (un_attended && fullscreen)
  75.     {
  76.         sb_move (filewin, 2, 2);
  77.         sb_puts (filewin, MSG_TXT (M_EMXMIT));
  78.         sb_show ();
  79.     }
  80.     else
  81.     {
  82.         set_xy (MSG_TXT (M_EMSEND));
  83.     }
  84.  
  85.     /*--------------------------------------------------------------------*/
  86.     /* Clean up any mess that may be around                               */
  87.     /*--------------------------------------------------------------------*/
  88.     CLEAR_INBOUND ();
  89.     XON_DISABLE ();
  90.  
  91.     if (!Send_EMSI_Packet (1))
  92.     {
  93.         sptr = MSG_TXT (M_HE_HUNG_UP);
  94.         status_line (sptr);
  95.         return (0);
  96.     }
  97.  
  98.     if (un_attended && fullscreen)
  99.     {
  100.         sb_move (filewin, 2, 2);
  101.         sb_puts (filewin, MSG_TXT (M_EMWAIT));
  102.         sb_show ();
  103.     }
  104.     else
  105.     {
  106.         set_xy (MSG_TXT (M_EMRECV));
  107.     }
  108.  
  109.     return Recv_EMSI_Packet (1);
  110. }
  111.  
  112. /*--------------------------------------------------------------------------*/
  113. /* EMSI RECEIVER  (Used when I am the CALLED system)                        */
  114. /*--------------------------------------------------------------------------*/
  115.  
  116. int 
  117. EMSI_Receiver (void)
  118. {
  119.     int i;
  120.  
  121.     highest_level = hl_aka = num_rakas = 0;
  122.     if (un_attended && fullscreen)
  123.     {
  124.         sb_move (filewin, 2, 2);
  125.         sb_puts (filewin, MSG_TXT (M_EMWAIT));
  126.         sb_show ();
  127.     }
  128.     else
  129.     {
  130.         set_xy (MSG_TXT (M_EMRECV));
  131.     }
  132.  
  133.     /*--------------------------------------------------------------------*/
  134.     /* Clean up any mess that may be around                               */
  135.     /*--------------------------------------------------------------------*/
  136.     CLEAR_OUTBOUND ();
  137.     XON_DISABLE ();
  138.  
  139.     if (Recv_EMSI_Packet (0) == 0)
  140.         return (0);
  141.  
  142.     if (un_attended && fullscreen)
  143.     {
  144.         sb_move (filewin, 2, 2);
  145.         sb_puts (filewin, MSG_TXT (M_EMXMIT));
  146.         sb_show ();
  147.     }
  148.     else
  149.     {
  150.         set_xy (MSG_TXT (M_EMSEND));
  151.     }
  152.  
  153.     if ((i = Send_EMSI_Packet (0)) == 0)
  154.         b_init ();
  155.     return (i);
  156. }                                /* EMSI Receiver */
  157.  
  158. /*--------------------------------------------------------------------------*/
  159. /* SEND EMSI PACKET                                                         */
  160. /*--------------------------------------------------------------------------*/
  161.  
  162. static int LOCALFUNC 
  163. Send_EMSI_Packet (int Sender)
  164. {
  165.     int i;
  166.     char *sptr;
  167.     long T1, T2;
  168.     word crc, len;
  169.     word tries = 0;
  170.     char *junkbuff, *uni;
  171.  
  172. /*
  173.  * Txbuf is (8192+16) in length
  174.  * junkbuff wants to be 4096
  175.  * uni wants to be 256
  176.  * We reserve the last 1024+16 for lower level functions
  177.  *
  178.  * If you change this way of doing things, you have to change
  179.  * Encode_EMSI_Header as well!!!
  180.  */
  181.  
  182.     junkbuff = (char *) Txbuf;
  183.     uni = &junkbuff[4096];
  184.  
  185.     /*--------------------------------------------------------------------*/
  186.     /* Setup EMSI structure                                               */
  187.     /*--------------------------------------------------------------------*/
  188.     len = Encode_EMSI_Header (junkbuff, Sender);
  189.  
  190.     /*--------------------------------------------------------------------*/
  191.     /* Disable handshaking and ^C/^K handling                             */
  192.     /*--------------------------------------------------------------------*/
  193.     XON_DISABLE ();
  194.  
  195.     /*--------------------------------------------------------------------*/
  196.     /* Send the packet.                                                   */
  197.     /* Load outbound buffer quickly, and get modem busy sending.          */
  198.     /*--------------------------------------------------------------------*/
  199.  
  200.     tries = 0;
  201.     T1 = timerset (6000);
  202.  
  203. xmit_packet:
  204.  
  205.     sprintf (uni, "%s%04X", &(emsistr[EMSI_DAT][2]), len);
  206.     crc = crc_block ((unsigned char *) uni, strlen (uni));
  207.     SENDCHARS ("**", 2, 1);
  208.     SENDCHARS (uni, strlen (uni), 1);
  209.     SENDCHARS (junkbuff, len, 1);
  210.  
  211.     /*--------------------------------------------------------------------*/
  212.     /* Calculate CRC while modem is sending its buffer                    */
  213.     /*--------------------------------------------------------------------*/
  214.     for (i = 0; i < (int) len; i++)
  215.         crc = xcrc (crc, junkbuff[i]);
  216.  
  217.     CLEAR_INBOUND ();
  218.     sprintf (uni, "%04X\r", crc);
  219.     SENDCHARS (uni, strlen (uni), 1);
  220.     if (tries++ > 6)
  221.     {
  222.         (void) sprintf (uni, "!%s", MSG_TXT (M_TIMEOUT));
  223.         sptr = uni;
  224.         goto no_response;
  225.     }
  226.  
  227.     /* wait_response: */
  228.  
  229.     T2 = timerset (2000);
  230.  
  231.     while (!timeup (T1) && CARRIER)
  232.     {
  233.         if (timeup (T2))
  234.             goto xmit_packet;
  235.  
  236.         if (!CHAR_AVAIL ())
  237.         {
  238.             if (got_ESC ())
  239.             {
  240.                 LOWER_DTR ();
  241.                 sptr = MSG_TXT (M_KBD_MSG);
  242.                 goto no_response;
  243.             }
  244.             time_release ();
  245.             continue;
  246.         }
  247.  
  248.         switch (i = TIMED_READ (0))
  249.         {
  250.         case '*':
  251.             strcpy (uni, "*");
  252.             if (!get_emsi (uni))
  253.                 break;
  254.             if (!stricmp (uni, emsistr[EMSI_REQ]))
  255.                 continue;
  256.             if (!stricmp (uni, emsistr[EMSI_ACK]))
  257.                 return (1);
  258.             goto xmit_packet;
  259.  
  260.         default:
  261.             if (i <= 0)            /* MB *//* Could just be line noise if > 0*/
  262.                 time_release ();/*PLF Sun  12-01-1991  04:21:14 */
  263.             break;
  264.         }
  265.     }
  266.  
  267.     if (!CARRIER)
  268.         sptr = MSG_TXT (M_NO_CARRIER);
  269.     else
  270.     {
  271.         (void) sprintf (uni, "!%s", MSG_TXT (M_TIMEOUT));
  272.         sptr = uni;
  273.     }
  274.  
  275. no_response:
  276.  
  277.     status_line (sptr);
  278.     return (0);
  279.  
  280. }                                /* Send EMSI */
  281.  
  282. /*--------------------------------------------------------------------------*/
  283. /* RECEIVE EMSI PACKET                                                      */
  284. /*--------------------------------------------------------------------------*/
  285.  
  286. static int LOCALFUNC 
  287. Recv_EMSI_Packet (int Sender)
  288. {
  289.     int i;
  290.     int c;
  291.     int len;
  292.     char *sptr;
  293.     byte tries = 0;
  294.     word crc, crc2;
  295.     long T1, T2, T3;
  296.     char *junkbuff, *uni, *help;
  297.  
  298. /*
  299.  * Txbuf is (8192+16) in length
  300.  * junkbuff wants to be 4096
  301.  * uni wants to be 256
  302.  * help wants to be 256
  303.  * tmpstr wants to be 256
  304.  * We reserve the last 1024+16 for lower level functions
  305.  *
  306.  * If you change this way of doing things, you have to change
  307.  * Decode_EMSI_Header as well!!!
  308.  */
  309.  
  310.     junkbuff = (char *) Txbuf;
  311.     uni = &junkbuff[4096];
  312.     help = &uni[256];
  313.     /* tmpstr = &help[256]; */
  314.  
  315.     /* strcpy (remote_sysop, "Sysop"); */
  316.     remote_password = NULL;
  317.  
  318.     /*--------------------------------------------------------------------*/
  319.     /* Get the EMSI structure                                             */
  320.     /*--------------------------------------------------------------------*/
  321.  
  322.     if (un_attended && fullscreen)
  323.     {
  324.         sb_move (filewin, 2, 2);
  325.         sb_puts (filewin, MSG_TXT (M_EMWAIT));
  326.         sb_show ();
  327.     }
  328.     else
  329.     {
  330.         set_xy (MSG_TXT (M_EMRECV));
  331.     }
  332.  
  333.     remote_pickup = 2;            /* Pickup for all akas */
  334.     T1 = timerset (2000);
  335.     T2 = timerset (6000);
  336.     sptr = NULL;
  337.  
  338. request_it:
  339.  
  340.     if (tries++ > 6)
  341.         goto timeout;
  342.  
  343.     if (!Sender)
  344.     {
  345.         sprintf (uni, "%s\r", emsistr[EMSI_REQ]);    /* EMSI_REQ if he called me  */
  346.     }
  347.     else if (tries > 1)
  348.     {
  349.         sprintf (uni, "%s\r", emsistr[EMSI_NAK]);    /* EMSI_NAK anytime after 1st*/
  350.     }
  351.     else
  352.         goto watch_for_header;
  353.  
  354.     SENDCHARS (uni, strlen (uni), 1);    /* Kick the other guy.       */
  355.  
  356. new_timer:
  357.  
  358.     T1 = timerset (2000);
  359.  
  360. watch_for_header:
  361.  
  362.     while (!timeup (T2) && CARRIER)
  363.     {
  364.         if (sptr)
  365.         {
  366.             status_line (sptr);
  367.             sptr = NULL;
  368.         }
  369.  
  370.         if (timeup (T1))
  371.             goto request_it;
  372.  
  373.         if (!CHAR_AVAIL ())
  374.         {
  375.             if (got_ESC ())
  376.             {
  377.                 LOWER_DTR ();
  378.                 sptr = MSG_TXT (M_KBD_MSG);
  379.                 goto receive_failed;
  380.             }
  381.             time_release ();
  382.             continue;
  383.         }
  384.  
  385.         switch (i = TIMED_READ (0))
  386.         {
  387.         case '*':
  388.             strcpy (uni, "*");
  389.             if (!get_emsi (uni))
  390.                 break;
  391.             if (!stricmp (uni, emsistr[EMSI_HBT]))
  392.                 goto new_timer;
  393.             if (!stricmp (uni, emsistr[EMSI_DAT]))
  394.                 goto receive_packet;
  395.             break;
  396.  
  397.         default:
  398.             if (i <= 0)            /* MB *//* Could just be line noise if > 0 */
  399.                 time_release ();/*PLF Sun  12-01-1991  04:21:14 */
  400.             break;
  401.         }
  402.     }
  403.  
  404.     if (timeup (T2))
  405.         goto timeout;
  406.  
  407.     if (!CARRIER)
  408.     {
  409.         sptr = MSG_TXT (M_NO_CARRIER);
  410.         goto receive_failed;
  411.     }
  412.  
  413. receive_packet:
  414.  
  415.     if (un_attended && fullscreen)
  416.     {
  417.         sb_move (filewin, 2, 2);
  418.         sb_puts (filewin, MSG_TXT (M_EMRCPT));
  419.         sb_show ();
  420.     }
  421.     T3 = timerset (6000);
  422.     if (((int) (uni[0] = (char) TIMED_READ (3)) < 0) ||
  423.         ((int) (uni[1] = (char) TIMED_READ (3)) < 0) ||
  424.         ((int) (uni[2] = (char) TIMED_READ (3)) < 0) ||
  425.         ((int) (uni[3] = (char) TIMED_READ (3)) < 0))
  426.     {
  427.         sptr = MSG_TXT (M_EMSHORT);
  428.         goto emsi_error;
  429.     }
  430.  
  431.     if (!CARRIER)
  432.     {
  433.         sptr = MSG_TXT (M_NO_CARRIER);
  434.         goto receive_failed;
  435.     }
  436.     uni[4] = '\0';
  437.     sscanf (uni, "%x", &len);
  438.     sprintf (help, "%s%s", &(emsistr[EMSI_DAT][2]), uni);
  439.     crc = crc_block ((unsigned char *) help, strlen (help));
  440.     sptr = junkbuff;
  441.     memset (junkbuff, 0, 4096);
  442.  
  443.     for (i = 0; i < len; i++)
  444.     {
  445.         while (PEEKBYTE () < 0)
  446.         {
  447.             if (timeup (T2) || timeup (T3))
  448.                 goto timeout;
  449.  
  450.             if (got_ESC ())
  451.             {
  452.                 sptr = MSG_TXT (M_KBD_MSG);
  453.                 goto receive_failed;
  454.             }
  455.  
  456.             if (!CARRIER)
  457.             {
  458.                 sptr = MSG_TXT (M_NO_CARRIER);
  459.                 goto receive_failed;
  460.             }
  461.  
  462.             time_release ();
  463.         }
  464.  
  465.         c = TIMED_READ (0);
  466.         *sptr++ = (char) c;
  467.         crc = xcrc (crc, (byte) c);
  468.     }
  469.  
  470.     if (((int) (uni[0] = (char) TIMED_READ (3)) < 0) ||
  471.         ((int) (uni[1] = (char) TIMED_READ (3)) < 0) ||
  472.         ((int) (uni[2] = (char) TIMED_READ (3)) < 0) ||
  473.         ((int) (uni[3] = (char) TIMED_READ (3)) < 0))
  474.     {
  475.         sptr = MSG_TXT (M_EMSHORT);
  476.         goto emsi_error;
  477.     }
  478.  
  479.     TIMED_READ (1);                /* What am I throwing away here? */
  480.  
  481.     if (!CARRIER)
  482.     {
  483.         sptr = MSG_TXT (M_NO_CARRIER);
  484.         goto receive_failed;
  485.     }
  486.  
  487.     uni[4] = '\0';
  488.     sscanf (uni, "%hx", &crc2);
  489.     if (crc == crc2)
  490.         goto process_packet;
  491.  
  492.     (void) sprintf (junkbuff, "!%s", MSG_TXT (M_CRC_MSG));
  493.     sptr = junkbuff;
  494.  
  495. emsi_error:
  496.  
  497.     if (timeup (T2))
  498.         goto timeout;
  499.  
  500.     CLEAR_INBOUND ();
  501.     goto request_it;
  502.  
  503. process_packet:
  504.  
  505.     if (strnicmp (junkbuff, "{EMSI}", 6))
  506.     {
  507.         sptr = MSG_TXT (M_EMSTART);
  508.         goto emsi_error;
  509.     }
  510.  
  511.     if (!Decode_EMSI_Header (junkbuff, len, Sender))
  512.         goto receive_failed;
  513.  
  514.     (void) n_getpassword (&remote_akas[hl_aka]);    /* Updated 'assumed', 'CURRENT' to match remote */
  515.  
  516.     CLEAR_INBOUND ();
  517.     CLEAR_OUTBOUND ();
  518.  
  519.     sprintf (uni, "%s\r", emsistr[EMSI_ACK]);
  520.     SENDCHARS (uni, strlen (uni), 1);    /* Let the other system know */
  521.     SENDCHARS (uni, strlen (uni), 1);    /* we got it !               */
  522.     T3 = timerset (1000);
  523.     while (!OUT_EMPTY ())        /* Flush the buffer          */
  524.     {
  525.         if (timeup (T3))
  526.             goto timeout;
  527.         if (!CARRIER)
  528.             goto receive_failed;
  529.         time_release ();
  530.     }
  531.  
  532.     return (1);
  533.  
  534. timeout:
  535.  
  536.     (void) sprintf (uni, "!%s", MSG_TXT (M_TIMEOUT));
  537.     sptr = uni;
  538.  
  539. receive_failed:
  540.  
  541.     status_line (sptr);
  542.     b_init ();
  543.     return (0);
  544. }                                /* Recv EMSI */
  545.  
  546. static int LOCALFUNC 
  547. get_emsi (char *s)
  548. {
  549.     long T1;
  550.     char *sptr, c;
  551.     int i;
  552.  
  553.     T1 = timerset (500);
  554.     sptr = s + 1;
  555.     memset (sptr, 0, EMSI_LEN + 1);
  556.     while (CARRIER)
  557.     {
  558.         while (PEEKBYTE () < 0)
  559.         {
  560.             if (timeup (T1))
  561.                 goto timeout;
  562.  
  563.             if (got_ESC ())
  564.             {
  565.                 status_line (MSG_TXT (M_KBD_MSG));
  566.                 goto receive_failed;
  567.             }
  568.  
  569.             if (!CARRIER)
  570.             {
  571.                 status_line (MSG_TXT (M_NO_CARRIER));
  572.                 goto receive_failed;
  573.             }
  574.  
  575.             time_release ();
  576.         }
  577.  
  578.         c = (char) TIMED_READ (0);
  579.         if (c == '\r')
  580.         {
  581.             status_line (">EMSI: '%s'", s);
  582.             return (1);
  583.         }
  584.         *sptr++ = (char) c;
  585.         for (i = 0; i < EMSI_MAX; i++)
  586.         {
  587.             if (!strnicmp (s, emsistr[i], strlen (emsistr[i])))
  588.             {
  589.                 status_line (">EMSI: '%s'", s);
  590.                 return (1);
  591.             }
  592.             else
  593.             {
  594.                 if ((int) strlen (s) > EMSI_LEN)
  595.                 {
  596.                     status_line (">EMSI: '%s'", s);
  597.                     return (1);
  598.                 }
  599.             }
  600.         }
  601.     }
  602. timeout:
  603.  
  604.     status_line ("!%s", MSG_TXT (M_TIMEOUT));
  605.  
  606. receive_failed:
  607.  
  608.     return (0);
  609. }
  610.  
  611. static char *LOCALFUNC 
  612. b7strcat (char *d, char *s)
  613. {
  614.     int i;
  615.     int j = strlen (s);
  616.     char uni[4], *p, *c;
  617.  
  618.     p = &d[strlen (d)];
  619.     c = s;
  620.     for (i = 0; i < j; c++, i++)
  621.     {
  622.         if (*c == '\\')
  623.         {
  624.             *p++ = '\\';
  625.             *p++ = '\\';
  626.             continue;
  627.         }
  628.  
  629.         /*old if((*c>=0)&&(*c<=0x7F)) */
  630.  
  631.         if (!(*c & 0x80))
  632.         {
  633.             *p++ = *c;
  634.             continue;
  635.         }
  636.         *p++ = '\\';            /* Do coding only for 8 bit chars */
  637.         sprintf (uni, "%02X", (unsigned) *c);
  638.         *p++ = uni[0];
  639.         *p++ = uni[1];
  640.         continue;
  641.     }
  642.     *p++ = '\0';
  643.     return (d);
  644. }
  645.  
  646. static LOCALFUNC 
  647. recode_from_b7 (char *s, int len)
  648. {
  649.     int i, j;
  650.     char *d, uni[4];
  651.     unsigned c;
  652.  
  653.     d = s;
  654.     for (j = i = 0; i < len; j++)
  655.     {
  656.         if (*s != '\\')
  657.         {
  658.             *d++ = *s++;
  659.             i++;
  660.             continue;
  661.         }
  662.         if (*++s == '\\')
  663.         {
  664.             *d++ = *s++;
  665.             i += 2;
  666.             continue;
  667.         }
  668.         uni[0] = *s++;
  669.         uni[1] = *s++;
  670.         uni[2] = '\0';
  671.         sscanf (uni, "%hx", &c);
  672.         *d++ = (char) c;
  673.         i += 3;
  674.     }
  675.     *d++ = '\0';
  676.     return (j);                    /* New length */
  677. }
  678.  
  679. static int LOCALFUNC 
  680. get_level (ADDRP addr, ADDRP myaka)
  681. {
  682.     int level = -1;
  683.  
  684.     if ((addr->Domain == myaka->Domain) || !addr->Domain || !myaka->Domain)
  685.         level++;
  686.     else
  687.         return (level);
  688.  
  689.     if (addr->Zone == myaka->Zone)
  690.         level++;
  691.     else
  692.         return (level);
  693.  
  694.     if (addr->Net == myaka->Net)
  695.         level++;
  696.     else
  697.         return (level);
  698.  
  699.     if (addr->Node == myaka->Node)
  700.         level++;
  701.     return (level);
  702. }
  703.  
  704. static int LOCALFUNC 
  705. match_aka (ADDRP addr)
  706. {
  707.     int level = -1;
  708.     int i, j;
  709.  
  710.     assumed = 0;
  711.     for (i = 0; i < num_addrs; i++)
  712.     {
  713.         j = get_level (addr, &alias[i]);
  714.         if (j > level)
  715.         {
  716.             assumed = i;
  717.             level = j;
  718.         }
  719.     }
  720.     return (0);
  721. }
  722.  
  723. /*--------------------------------------------------------------------------*/
  724. /* Find end of EMSI field                                                   */
  725. /*--------------------------------------------------------------------------*/
  726.  
  727. static char *LOCALFUNC 
  728. get_bracket (char *p)
  729. {
  730.     register char c;
  731.     register char x = *(p - 1);    /* Save starting character */
  732.     char *q = p;
  733.  
  734.     /* Convert starting bracket to expected ending bracket */
  735.  
  736.     if (x == '{')
  737.         x = '}';
  738.     else if (x == '[')
  739.         x = ']';
  740.  
  741.     while ((c = *p++) != '\0')
  742.     {
  743.         /* If this is an ending bracket */
  744.  
  745.         if (c == '}' || c == ']')
  746.         {
  747.             /* And it's not escaped */
  748.  
  749.             if (*p != c)
  750.             {
  751.                 /* And it's the right one, get out. */
  752.  
  753.                 if (c == x)
  754.                     break;
  755.             }
  756.             else
  757.             {
  758.                 /* If it is escaped, copy the end of the string over the esc */
  759.  
  760.                 strcpy (q, p);
  761.             }
  762.         }
  763.         q = p;
  764.     }
  765.     return (q);
  766. }
  767.  
  768. static char *LOCALFUNC 
  769. cat_bracket (char *d, char *c)        /* MB 93-11-27 */
  770. {
  771.     char x, *p, *q;
  772.     q = p = (char *) &Txbuf[7168];
  773.  
  774.     while ((x = *c++) != '\0')
  775.     {
  776.         if (*c && (x == '}' || x == ']'))
  777.             *p++ = x;    /* We have to escape } or ] by doing it twice */
  778.         *p++ = x;
  779.     }
  780.     *p++ = '\0';
  781.     return (b7strcat (d, q));
  782. }
  783.  
  784. static int LOCALFUNC 
  785. Decode_EMSI_Header (char *junkbuff, int len, int Sender)
  786. {
  787.     int i, akacnt = 0;
  788.     int prodcodeT, logit = TRUE;
  789.     int j, addonnr;
  790.     long lmoh = 0;
  791.     int cur = 0;
  792.     char *tmpstr, *sptr, *p;
  793.     char *uni, *help, *name, *loc, password[16];
  794.     ADDR addr[ALIAS_CNT], remote;
  795.     static char *addons[] = {"{IDENT}", "{TRX#}", "{MOH#}", NULL};
  796.  
  797.     uni = &junkbuff[4096];        /* Look at Recv_EMSI_Packet to see */
  798.     help = &uni[256];            /* why this is OK                  */
  799.     tmpstr = &help[256];
  800.  
  801.     recode_from_b7 (junkbuff, len);
  802.     sptr = &junkbuff[7];
  803.     memset (&remote_addr, 0, sizeof (remote_addr));
  804.     akacnt = i = 0;
  805.     while (*sptr != '}')
  806.     {
  807.         while (*sptr == ' ')
  808.             sptr++;
  809.  
  810.         /* Copy the address string into temp string. */
  811.  
  812.         p = tmpstr;
  813.         while (*sptr && *sptr != '}' && *sptr != ' ')
  814.             *p++ = *sptr++;
  815.         *p = '\0';
  816.         if (p == tmpstr)
  817.             break;
  818.         memset (&addr[i], 0, sizeof (ADDR));
  819.         status_line (">EMSI: parsing addr: '%s'", tmpstr);
  820.         (void) find_address (tmpstr, &addr[i]);
  821.         status_line (">EMSI: got addr: '%s'", Full_Addr_Str (&addr[i]));
  822.         /*    sscanf(sptr,"%u:%u/%u.%u",&addr[i].Zone,&addr[i].Net,&addr[i].Node,&addr[i].Point); */
  823.         if (Sender && (addr[i].Zone == called_addr.Zone) && (addr[i].Net == called_addr.Net) && (addr[i].Node == called_addr.Node) && (addr[i].Point == called_addr.Point))
  824.             remote_addr = addr[i];
  825.         if (i < (ALIAS_CNT - 1))
  826.             i++;
  827.     }
  828.     akacnt = i;
  829.     if (!remote_addr.Zone || !remote_addr.Net)
  830.         remote_addr = addr[0];
  831.  
  832.     while (*sptr++ != '{')
  833.         ;
  834.     i = 0;
  835.     while (*sptr != '}')
  836.         password[i++] = *sptr++;
  837.     password[i] = '\0';
  838.     sptr++;
  839.     while (*sptr != '}')
  840.     {
  841.         i = 0;
  842.         while ((*sptr != ',') && (*sptr != '}'))
  843.             uni[i++] = *sptr++;
  844.         uni[i] = '\0';
  845.         if (*sptr != '}')
  846.             sptr++;
  847.         if (!stricmp (uni, "NPU"))
  848.             remote_pickup = 0;
  849.         else if (!stricmp (uni, "PUP"))
  850.             remote_pickup = 1;
  851.         else if (!stricmp (uni, "PUA"))
  852.             remote_pickup = 2;
  853.     }
  854.     sptr++;
  855.     sptr++;
  856.     remote_capabilities = WZ_FREQ;
  857.     while (*sptr != '}')
  858.     {
  859.         i = 0;
  860.         while ((*sptr != ',') && (*sptr != '}'))
  861.             uni[i++] = *sptr++;
  862.         uni[i] = '\0';
  863.         if (*sptr != '}')
  864.             sptr++;
  865.         if (!stricmp (uni, "JAN"))
  866.             remote_capabilities |= DOES_IANUS;
  867. #ifdef HAVE_HYDRA
  868.         else if (!stricmp (uni, "HYD"))
  869.             remote_capabilities |= DOES_HYDRA;
  870. #endif    /* HAVE_HYDRA */
  871.         else if (!stricmp (uni, "ZAP"))
  872.             remote_capabilities |= ZED_ZAPPER;
  873.         else if (!stricmp (uni, "ZMO"))
  874.             remote_capabilities |= ZED_ZIPPER;
  875.         else if (!stricmp (uni, "NRQ"))
  876.             remote_capabilities &= ~WZ_FREQ;
  877.     }
  878.     sptr++;
  879.     sptr++;
  880.     sscanf (sptr, "%x", &prodcodeT);
  881.     /*   remote_mailer=prodcode; */
  882.     while (*sptr++ != '{')
  883.         ;
  884.     i = 0;
  885.     while (*sptr != '}')
  886.         uni[i++] = *sptr++;
  887.     sptr++;
  888.     sptr++;
  889.     uni[i++] = ' ';
  890.     while (*sptr != '}')
  891.         uni[i++] = *sptr++;
  892.     sptr++;
  893.     sptr++;
  894.     uni[i++] = '/';
  895.     while (*sptr != '}')
  896.         uni[i++] = *sptr++;
  897.     if (uni[--i] != '/')
  898.         i++;
  899.     uni[i] = '\0';
  900.     sptr++;
  901.     for (;;)
  902.     {
  903.         if (*sptr != '{')
  904.             break;
  905.  
  906.         for (addonnr = 0; addons[addonnr] != NULL; addonnr++)
  907.         {
  908.             if (!strnicmp (sptr, addons[addonnr], strlen (addons[addonnr])))
  909.                 break;
  910.         }
  911.  
  912.         if (!addons[addonnr])    /* no known addon */
  913.             addonnr = 0;
  914.         else
  915.             addonnr++;
  916.  
  917.         switch (addonnr)
  918.         {
  919.         case 1:                /* {IDENT} system name */
  920.             sptr += 9;
  921.             name = sptr;
  922.             sptr = get_bracket (sptr);
  923.             *sptr = '\0';
  924.  
  925.             (void) sprintf (help, "*%s (%s)", name, Full_Addr_Str (&remote_addr));
  926.             status_line ("%s", help);
  927.             if (akacnt > 1)
  928.             {
  929.                 strcpy (help, ":Aka: ");
  930.                 for (j = i = 0; i < akacnt; i++)
  931.                 {
  932.                     if (!memcmp (&addr[i], &remote_addr, sizeof (ADDR)))
  933.                         continue;
  934.                     strcat (help, Full_Addr_Str (&addr[i]));
  935.                     strcat (help, " ");
  936.                     if (++j == 3)
  937.                     {
  938.                         status_line ("%s", help);
  939.                         strcpy (help, ":     ");
  940.                         j = 0;
  941.                     }
  942.                 }
  943.                 if (j)
  944.                     status_line ("%s", help);
  945.             }
  946.             sptr += 2;
  947.             status_line ("%s %s", MSG_TXT (M_REMOTE_USES), uni);
  948.             loc = sptr;
  949.             sptr = get_bracket (sptr);
  950.             *sptr = '\0';
  951.             *uni = '\0';
  952.             if (loc[0])
  953.                 sprintf (uni, " from %s", loc);
  954.             sptr += 2;
  955.             name = sptr;
  956.             sptr = get_bracket (sptr);
  957.             *sptr = '\0';
  958.             if (name[0])
  959.             {
  960.                 status_line (":SysOp: %s%s", name, uni);
  961.                 /*             strcpy (remote_sysop,name);  */
  962.             }
  963.  
  964.             sptr += 2;            /* phone */
  965.             name = sptr;
  966.             sptr = get_bracket (sptr);
  967.             *sptr = '\0';
  968.             sptr += 2;
  969.  
  970.             sptr = get_bracket (sptr);    /* baud */
  971.             *sptr = '\0';
  972.  
  973.             sptr += 2;            /* flags */
  974.             loc = sptr;
  975.             sptr = get_bracket (sptr);
  976.             *sptr = '\0';
  977.             if (loc[0] && name[0] && strcmp (name, "-Unpublished-"))
  978.             {
  979.                 status_line (" Phone: %s", name);
  980.                 status_line (" Flags: %s", loc);
  981.             }
  982.             while (*sptr++ != '}')
  983.                 ;
  984.             break;
  985.  
  986.         case 2:                /* {TRX#}  tranx */
  987.             sptr += 8;
  988.             name = sptr;
  989.             sptr = get_bracket (sptr);
  990.             *sptr = '\0';
  991. #ifdef ANSI_TIME_T
  992.             status_line (":Tranx: %08lX / %s", etm - ANSI_TIME_T_DELTA, name);
  993. #else
  994.             status_line (":Tranx: %08lX / %s", etm, name);
  995. #endif
  996.             while (*sptr++ != '}')
  997.                 ;
  998.             break;
  999.  
  1000.         case 3:                /* {MOH#}  mail on hold */
  1001.             sptr += 8;
  1002.             name = sptr;
  1003.             sptr = get_bracket (sptr);
  1004.             *sptr = '\0';
  1005.             sscanf (name, "%lX", &lmoh);
  1006.             status_line (">Mail on Hold: %ldb", lmoh);
  1007.             while (*sptr++ != '}')
  1008.                 ;
  1009.             break;
  1010.  
  1011.         default:                /* any other addon */
  1012.             name = ++sptr;
  1013.             while (*sptr != '}')
  1014.                 sptr++;            /* goto end of addon  string */
  1015.             *sptr++ = '\0';
  1016.             loc = ++sptr;
  1017.             sptr = get_bracket (sptr);    /* MB  new  */
  1018.             *sptr++ = '\0';
  1019.             status_line (">Unknown EMSI Addon: %s: {%s}", name, loc);
  1020.             break;
  1021.         }
  1022.     }
  1023.     remote = remote_addr;
  1024.     if (!remote_pickup)
  1025.         status_line (" Remote refused mail-pickup");
  1026.     if (Sender)
  1027.         remote_addr = called_addr;
  1028.     CURRENT = DEFAULT;
  1029.  
  1030.     for (i = 0; i <= akacnt; i++)
  1031.     {
  1032.         status_line (">EMSI: checking addr: '%s'", Full_Addr_Str (&remote_addr));
  1033.         if ((j = n_getpassword (&remote_addr)) > 0)
  1034.         {
  1035.             if (Sender && *remote_password && !*password && (prodcodeT == isDBRIDGE))
  1036.                 j = 0;            /* work-around for a D'Bridge(tm)-Bug */
  1037.             else
  1038.                 j = n_password (password, remote_password, &logit);
  1039.  
  1040.             status_line (">EMSI: result of pw check: '%d'", j);
  1041.  
  1042.             if (j == 0)
  1043.             {
  1044.                 if (highest_level < 2)
  1045.                 {
  1046.                     highest_level = 2;
  1047.                     hl_aka = num_rakas;
  1048.                 }
  1049.             }
  1050.             else
  1051.             {
  1052.          /*
  1053.           * Password doesn't match.
  1054.           *
  1055.           * Result of 1 means both of us had one.
  1056.           *
  1057.           * Result of 2 means we had one and the other side didn't.
  1058.           *
  1059.           * If we are the sender we will accept this mismatch,
  1060.           * but only on the first aka.
  1061.           *
  1062.           */
  1063.                 if ((!Sender) || (num_rakas != 0))
  1064.                     goto next_one;
  1065.                 else
  1066.                     status_line (MSG_TXT (M_PASSWORD_OVERRIDE));
  1067.  
  1068.                 if (highest_level < 1)
  1069.                 {
  1070.                     highest_level = 1;
  1071.                     hl_aka = num_rakas;
  1072.                 }
  1073.             }
  1074.         }
  1075.         else if (j < 0)
  1076.         {
  1077.             status_line (">EMSI: addr '%s' will be curmudgeoned", Full_Addr_Str (&remote_addr));
  1078.             cur = 1;
  1079.             goto next_one;
  1080.         }
  1081.  
  1082.         status_line (">EMSI: checking addr '%s' for dupe", Full_Addr_Str (&remote_addr));
  1083.         for (j = 0; j < num_rakas; j++)
  1084.         {
  1085.             if (get_level (&remote_addr, &(remote_akas[j])) == 3)
  1086.                 goto next_one;
  1087.         }
  1088.  
  1089.         status_line (">EMSI: using addr: '%s'", Full_Addr_Str (&remote_addr));
  1090.         remote_akas[num_rakas++] = remote_addr;
  1091.  
  1092. next_one:
  1093.  
  1094.         remote_addr = addr[i];
  1095.     }
  1096.     if (!num_rakas)
  1097.     {
  1098.         if (cur)
  1099.             sptr = MSG_TXT (M_NUISANCE_CALLER);
  1100.         else
  1101.             sptr = NULL;
  1102.  
  1103.         LOWER_DTR ();            /* He'll never get it right */
  1104.         timer (2);                /* Wait two secs */
  1105.         return (0);
  1106.     }
  1107.  
  1108.     remote_addr = remote;
  1109.  
  1110.     return (1);
  1111. }
  1112.  
  1113. static int LOCALFUNC 
  1114. Encode_EMSI_Header (char *junkbuff, int Sender)
  1115. {
  1116.     int i, capabilities = 0;
  1117.     char *uni;
  1118.  
  1119.     uni = &junkbuff[4096];        /* See why this is OK in Send_EMSI_Packet */
  1120.  
  1121.     strcpy (junkbuff, "{EMSI}");
  1122.     b7strcat (junkbuff, "{");
  1123.     match_aka (&remote_addr);    /* Update 'assumed' */
  1124.     status_line (">Used Aka: %s", Full_Addr_Str (&alias[assumed]));
  1125.  
  1126.     b7strcat (junkbuff, Full_Addr_Str (&alias[assumed]));
  1127.     for (i = 0; i < num_addrs; i++)
  1128.     {
  1129.         if (i != assumed)
  1130.         {
  1131.             b7strcat (junkbuff, " ");
  1132.             b7strcat (junkbuff, Full_Addr_Str (&alias[i]));
  1133.         }
  1134.     }
  1135.  
  1136.     b7strcat (junkbuff, "}{");
  1137.     remote_password = NULL;
  1138.     if ((Sender && (n_getpassword (&remote_addr) > 0)) ||
  1139.         (!Sender && (n_getpassword (&remote_akas[hl_aka]) > 0)))
  1140.     {
  1141.         if (remote_password)
  1142.         {
  1143.             (void) strncpy ((char *) uni, remote_password, 8);
  1144.             uni[8] = '\0';
  1145.             b7strcat (junkbuff, uni);
  1146.         }
  1147.     }
  1148.     b7strcat (junkbuff, "}{8N1");
  1149.     if (Sender)
  1150.     {
  1151.         if (!no_pickup)
  1152.         {
  1153.             if (pickup_all)
  1154.                 b7strcat (junkbuff, ",PUA");
  1155.             else
  1156.                 b7strcat (junkbuff, ",PUP");
  1157.         }
  1158.         else
  1159.             b7strcat (junkbuff, ",NPU");
  1160.     }
  1161.     else
  1162.     {
  1163.         if (matrix_mask & NO_TRAFFIC)
  1164.             b7strcat (junkbuff, ",HAT");
  1165.         if (!(matrix_mask & TAKE_REQ))
  1166.             b7strcat (junkbuff, ",HRQ");
  1167.     }
  1168.     b7strcat (junkbuff, "}{");
  1169.  
  1170.     /* At least one ZModem protocol must be available for FSC-0056 ! */
  1171.  
  1172.     if (!my_capabilities & ZED_ZIPPER)
  1173.         my_capabilities |= ZED_ZIPPER;
  1174.  
  1175. /*
  1176.  * If we are the calling system, turn on all our capabilities.
  1177.  * If we are the called system, choose from the set that the
  1178.  * caller gave us, and only send the one we prefer.
  1179.  */
  1180.     if (!Sender)
  1181.     {
  1182.         if (remote_capabilities & my_capabilities & DOES_IANUS)
  1183.             capabilities = DOES_IANUS;
  1184. #ifdef HAVE_HYDRA
  1185.         else if (remote_capabilities & my_capabilities & DOES_HYDRA)
  1186.             capabilities = DOES_HYDRA;
  1187. #endif    /* HAVE_HYDRA */
  1188.         else if (remote_capabilities & my_capabilities & ZED_ZAPPER)
  1189.             capabilities = ZED_ZAPPER;
  1190.         else if (remote_capabilities & my_capabilities & ZED_ZIPPER)
  1191.             capabilities = ZED_ZIPPER;
  1192.     }
  1193.     else
  1194.         capabilities = my_capabilities;
  1195.  
  1196. #ifdef HAVE_HYDRA
  1197.     if (!capabilities & (DOES_IANUS | DOES_HYDRA | ZED_ZAPPER | ZED_ZIPPER))
  1198. #else
  1199.     if (!capabilities & (DOES_IANUS | ZED_ZAPPER | ZED_ZIPPER))
  1200. #endif    /* HAVE_HYDRA */
  1201.         b7strcat (junkbuff, "NCP,");
  1202.     else if (Sender)
  1203.     {
  1204.         if (capabilities & DOES_IANUS)
  1205.             b7strcat (junkbuff, "JAN,");
  1206. #ifdef HAVE_HYDRA
  1207.         if (capabilities & DOES_HYDRA)
  1208.             b7strcat (junkbuff, "HYD,");
  1209. #endif    /* HAVE_HYDRA */
  1210.         if (capabilities & ZED_ZAPPER)
  1211.             b7strcat (junkbuff, "ZAP,");
  1212.         if (capabilities & ZED_ZIPPER)
  1213.             b7strcat (junkbuff, "ZMO,");
  1214.     }
  1215.     else
  1216.     {
  1217.         if (capabilities & DOES_IANUS)
  1218.             b7strcat (junkbuff, "JAN,");
  1219. #ifdef HAVE_HYDRA
  1220.         else if (capabilities & DOES_HYDRA)
  1221.             b7strcat (junkbuff, "HYD,");
  1222. #endif    /* HAVE_HYDRA */
  1223.         else if (capabilities & ZED_ZAPPER)
  1224.             b7strcat (junkbuff, "ZAP,");
  1225.         else if (capabilities & ZED_ZIPPER)
  1226.             b7strcat (junkbuff, "ZMO,");
  1227.     }
  1228.     if (!(matrix_mask & TAKE_REQ) || (Sender && !on_our_nickel))
  1229.     {
  1230.         b7strcat (junkbuff, "NRQ,");
  1231.     }
  1232.     else
  1233.         capabilities |= WZ_FREQ;
  1234.  
  1235.     b7strcat (junkbuff, "ARC,XMA");
  1236.     b7strcat (junkbuff, ",FNC");
  1237.     b7strcat (junkbuff, "}");                    /* MB 93-11-27 */
  1238.     sprintf (uni, "{%02X}", PRDCT_CODE);
  1239.     b7strcat (junkbuff, uni);
  1240.     sprintf (uni, "{%s}", PRDCT_PRTY);
  1241.     cat_bracket (junkbuff, uni);
  1242.     sprintf (uni, "{%d.%02d}",
  1243.         BINK_MAJVERSION,                        /*  vvv  */ 
  1244.         BINK_MINVERSION);
  1245.     b7strcat (junkbuff, uni);
  1246.     sprintf (uni, "{%s}", ((serial == -1) ? MSG_TXT (M_UNREGISTERED) : ""));
  1247.     cat_bracket (junkbuff, uni);
  1248.     b7strcat (junkbuff, "{IDENT}{");
  1249.     sprintf (uni, "[%s]", system_name);          
  1250.     cat_bracket (junkbuff, uni);
  1251.     sprintf (uni, "[%s]", location);            /*  vvv  */ 
  1252.     cat_bracket (junkbuff, uni);
  1253.     sprintf (uni, "[%s]", sysop);
  1254.     cat_bracket (junkbuff, uni);                  
  1255.     sprintf (uni, "[%s]", myphone);
  1256.     cat_bracket (junkbuff, uni);
  1257.     sprintf (uni, "[%s]", mymaxbaud);
  1258.     cat_bracket (junkbuff, uni);
  1259.     sprintf (uni, "[%s]", myflags);
  1260.     cat_bracket (junkbuff, uni);                /* MB 93-11-27 */
  1261.     b7strcat (junkbuff, "}{TRX#}");
  1262. #ifdef ANSI_TIME_T
  1263.     sprintf (uni, "{[%08lX]}", etm - ANSI_TIME_T_DELTA);
  1264. #else
  1265.     sprintf (uni, "{[%08lX]}", etm);
  1266. #endif
  1267.     b7strcat (junkbuff, uni);
  1268.     return (strlen (junkbuff));
  1269. }
  1270.  
  1271. /* END OF FILE: emsi.c */
  1272.